"""
x86 特有的特有数据类型 包含 /usr/include/asm/kvm.h 和 /usr/include/linux/kvm.h
"""

from ctypes import *
from enum import *

from ioctl_opt import IO, IOW, IOR

KVM_IOAPIC_NUM_PINS = 24


class kvm_memory_alias(Structure):
    _fields_ = [
        ('slot', c_uint32),
        ('flags', c_uint32),
        ('guest_phys_addr', c_uint64),
        ('memory_size', c_uint64),
        ('target_phys_addr', c_uint64),
    ]


class _kvm_ioapic_state_fields(Structure):
    _fields_ = [
        ("vector", c_uint8),
        ("delivery_mode:3", c_uint8, 3),
        ("dest_mode:1", c_uint8, 1),
        ("delivery_status:1", c_uint8, 1),
        ("polarity:1", c_uint8, 1),
        ("remote_irr:1", c_uint8, 1),
        ("trig_mode:1", c_uint8, 1),
        ("mask:1", c_uint8, 1),
        ("reserve:7", c_uint8, 7),
        ("reserved[4]", c_uint8 * 4),
        ("dest_id", c_uint8),
    ]


class _kvm_ioapic_state_redirtbl(Union):
    _fields_ = [
        ('bits', c_uint64),
        ('fields', _kvm_ioapic_state_fields),
    ]


class kvm_ioapic_state(Structure):
    _fields_ = [
        ('base_address', c_uint64),
        ('ioregsel', c_uint32),
        ('id', c_uint32),
        ('irr', c_uint32),
        ('pad', c_uint32),
        ('redirtbl', _kvm_ioapic_state_redirtbl * KVM_IOAPIC_NUM_PINS)
    ]


# 用于 KVM_SET_IRQCHIP KVM_GET_IRQCHIP
class kvm_pic_state(Union):
    __fields__ = [
        ("last_irr", c_uint8),
        ("irr", c_uint8),
        ("imr", c_uint8),
        ("isr", c_uint8),
        ("priority_add", c_uint8),
        ("irq_base", c_uint8),
        ("read_reg_select", c_uint8),
        ("poll", c_uint8),
        ("special_mask", c_uint8),
        ("init_state", c_uint8),
        ("auto_eoi", c_uint8),
        ("rotate_on_auto_eoi", c_uint8),
        ("special_fully_nested_mode", c_uint8),
        ("init4", c_uint8),
        ("elcr", c_uint8),
        ("elcr_mask", c_uint8),
    ]


class _kvm_irqchip_uni(Union):
    __fields__ = [
        ('dummy', c_char * 512),
        ('pic', kvm_pic_state),
        ('ioapic', kvm_ioapic_state)
    ]


# 用于 KVM_GET_REGS KVM_SET_REGS
class kvm_regs(Structure):
    __fields__ = [
        ("rax,", c_uint64),
        ("rbx,", c_uint64),
        ("rcx,", c_uint64),
        ("rdx", c_uint64),
        ("rsi,", c_uint64),
        ("rdi,", c_uint64),
        ("rsp,", c_uint64),
        ("rbp", c_uint64),
        ("r8,", c_uint64),
        ("r9,", c_uint64),
        ("r10,", c_uint64),
        ("r11", c_uint64),
        ("r12,", c_uint64),
        ("r13,", c_uint64),
        ("r14,", c_uint64),
        ("r15", c_uint64),
        ("rip,", c_uint64),
        ("rflags", c_uint64),
    ]


class kvm_segment(Structure):
    __fields__ = [
        ("base", c_uint64),
        ("limit", c_uint32),
        ("selector", c_uint16),
        ("type", c_uint8),
        ("present", c_uint8),
        ("dpl", c_uint8),
        ("db", c_uint8),
        ("s", c_uint8),
        ("l", c_uint8),
        ("g", c_uint8),
        ("val", c_uint8),
        ("unusable", c_uint8),
        ("padding", c_uint8),
    ]

class kvm_dtable(Structure):
    __fields__ = [
        ("base", c_uint64),
        ("limit", c_uint16),
        ("padding", c_uint16*3),
    ]

# 用于 KVM_GET_SREGS KVM_SET_SREGS
class kvm_sregs(Structure):
    __fields__ = [

    ]


class kvm_sync_regs(Structure):
    __fields__ = [
        ('regs', kvm_regs),
        ('sregs', kvm_sregs),
        ('events', kvm_vcpu_events),
    ]
